<template>
  <MainContent>
    <div id="visGraph" class="vis-demo" v-loading="loading"></div>
  </MainContent>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import vis from 'vis'

const options = {
  layout: {
    improvedLayout: false,
    hierarchical: {
      enabled: false,
      levelSeparation: 200,
      nodeSpacing: 200,
      treeSpacing: 250,
      blockShifting: true,
      edgeMinimization: true,
      parentCentralization: true,
      direction: 'UD',
      sortMethod: 'hubsize'
    }
  },
  nodes: {
    size: 16,
    borderWidth: 1.5,
    borderWidthSelected: 3,
    font: { color: '#000', size: 10 }
  },
  edges: {
    arrows: {
      to: {
        enabled: true,
        type: 'arrow'
      }
    },
    smooth: {
      type: 'cubicBezier',
      roundness: 0.5
    },
    font: { color: '#555', size: 10 }
  },
  physics: {
    barnesHut: {
      gravitationalConstant: -3000
    },
    forceAtlas2Based: {
      gravitationalConstant: -1500
    },
    stabilization: {
      updateInterval: 1500,
      iterations: 222
    },
    timestep: 1
  },
  interaction: {
    hover: true,
    hoverConnectedEdges: true
  },
  manipulation: {
    enabled: false
  }
}

const loading = ref(false)
const isInit = ref(true)

const createImg = (item:any) => {
  const nodeContain = 'overflow:hidden;border-radius:5px;height:100%;box-sizing:border-box;'
  const divContain =
    'background-color:rgba(255,255,255,1);height:100%;display:flex;align-items:center;justify-content:center;font-size:15px;'
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="120" height="50">
          <foreignObject x="0" y="0" width="100%" height="100%">
            <div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid #000;${nodeContain}">
              <div style="${divContain}">${item.label}</div>
            </div>
          </foreignObject>
        </svg>`

  return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`
}

const initData = () => {
  const data = {
    nodes: [
      { label: '股票', id: 'fsdfsaf1', group: '1', shape: 'dot', image: '' },
      { label: '基金公司', id: 'fsdfsaf2', group: '1', shape: 'dot', image: '' },
      { label: '股票报告', id: 'fsdfsaf3', group: '2', shape: 'box', image: '' },
      { label: '股票评级', id: 'fsdfsaf4', group: '2', shape: 'box', image: '' },
      { label: '股票代码', id: 'fsdfsaf5', group: '3', shape: 'dot', image: '' },
      { label: '股票变化', id: 'fsdfsaf6', group: '3', shape: 'dot', image: '' },
      { label: '股票类型', id: 'fsdfsaf7', group: '4', shape: 'dot', image: '' },
      { label: '散户', id: 'fsdfsaf8', group: '5', shape: 'dot', image: '' }
    ],
    edges: [
      {
        from: 'fsdfsaf1',
        to: 'fsdfsaf2',
        label: '关系'
      },
      {
        from: 'fsdfsaf1',
        to: 'fsdfsaf2',
        label: '关系2'
      },
      {
        from: 'fsdfsaf1',
        to: 'fsdfsaf2',
        label: '关系3'
      },
      {
        from: 'fsdfsaf2',
        to: 'fsdfsaf2',
        label: '关系'
      },
      {
        from: 'fsdfsaf1',
        to: 'fsdfsaf3',
        label: '关系'
      },
      {
        from: 'fsdfsaf1',
        to: 'fsdfsaf4',
        label: '关系'
      },
      {
        from: 'fsdfsaf2',
        to: 'fsdfsaf5',
        label: '关系'
      },
      {
        from: 'fsdfsaf2',
        to: 'fsdfsaf6',
        label: '关系'
      },
      {
        from: 'fsdfsaf2',
        to: 'fsdfsaf7',
        label: '关系'
      },
      {
        from: 'fsdfsaf8',
        to: 'fsdfsaf1',
        label: '韭菜、机构'
      }
    ]
  }

  data.nodes.forEach((item) => {
    if (item.group === '1') {
      item.shape = 'image'
      item.image = createImg(item)
    }
  })

  return data
}

const init = () => {
  const data = initData()
  const networkInstance = new vis.Network(document.getElementById('visGraph'), data, options)

  networkInstance.on('startStabilizing', () => {
    if (isInit.value) {
      loading.value = true
      isInit.value = false
    }
  })

  networkInstance.on('stabilizationIterationsDone', () => {
    networkInstance.setOptions({ physics: false })
    loading.value = false
  })

  networkInstance.on('click', (properties:any) => {
    if (properties.nodes.length === 0) {
      return
    }
    console.info(properties)
  })

  networkInstance.on('blurNode', (properties:any) => {
    //console.info(properties)
  })
}

onMounted(() => {
  init()
})
</script>

<style lang="scss" scoped>
@import './VisDemo.scss';
</style>
